#!/usr/bin/env python3
import psutil
import GPUtil
import pymysql
from datetime import datetime
#pip install psutil GPUtil pymysql schedule
def connect_db():
    try:
        conn = pymysql.connect(
            host='',
            port=26945,
            user='root',
            password='',
            database='server-monitoring',
            charset='utf8mb4'
        )
        return conn
    except Exception as e:
        print(f"Database connection error: {e}")
        return None

def save_to_db(ip,cpu_usage, disk_total, disk_usage, gpus):
    conn = connect_db()
    if not conn:
        return
    
    try:
        with conn.cursor() as cursor:
            # Prepare GPU data (support up to 8 GPUs)
            gpu_data = {}
            for i in range(8):
                if i < len(gpus):
                    gpu = gpus[i]
                    gpu_data.update({
                        f'gpu{i}name': gpu.name,
                        f'gpu{i}cUsage': float(gpu.load*100),
                        f'gpu{i}m': int(gpu.memoryTotal),
                        f'gpu{i}mUsage': float(gpu.memoryUtil*100)
                    })
                else:
                    gpu_data.update({
                        f'gpu{i}name': None,
                        f'gpu{i}cUsage': None,
                        f'gpu{i}m': None,
                        f'gpu{i}mUsage': None
                    })

            # Get server IP (simplified, in production should get actual IP)
            

            sql = """
            INSERT INTO system_monitor (
                ip, CPUUsage, disktotal, diskUsage,
                gpu0name, gpu0cUsage, gpu0m, gpu0mUsage,
                gpu1name, gpu1cUsage, gpu1m, gpu1mUsage,
                gpu2name, gpu2cUsage, gpu2m, gpu2mUsage,
                gpu3name, gpu3cUsage, gpu3m, gpu3mUsage,
                gpu4name, gpu4cUsage, gpu4m, gpu4mUsage,
                gpu5name, gpu5cUsage, gpu5m, gpu5mUsage,
                gpu6name, gpu6cUsage, gpu6m, gpu6mUsage,
                gpu7name, gpu7cUsage, gpu7m, gpu7mUsage
            ) VALUES (
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s,
                %s, %s, %s, %s
            )
            """
            cursor.execute(sql, (
                ip, float(cpu_usage), int(disk_total), float(disk_usage),
                *[gpu_data[f'gpu{i}{field}'] for i in range(8) for field in ['name', 'cUsage', 'm', 'mUsage']]
            ))
        conn.commit()
    except Exception as e:
        print(f"Error saving to database: {e}")
    finally:
        conn.close()

def get_cpu_usage():
    try:
        cpu_percent = psutil.cpu_percent(interval=1)
        print(f"Current CPU Usage: {cpu_percent}%")
        return cpu_percent
    except Exception as e:
        print(f"Error getting CPU usage: {e}")
        return None

def get_disk_usage():
    try:
        disk = psutil.disk_usage('/')
        print("\nDisk Information:")
        print(f"Total: {disk.total / (1024**3):.2f} GB")
        print(f"Used: {disk.used / (1024**3):.2f} GB")
        print(f"Free: {disk.free / (1024**3):.2f} GB")
        print(f"Usage Percentage: {disk.percent}%")
        return disk.total / (1024**3), disk.percent
    except Exception as e:
        print(f"Error getting disk usage: {e}")
        return None, None

def get_gpu_usage():
    try:
        gpus = GPUtil.getGPUs()
        if len(gpus) > 0:
            print("\nGPU Information:")
            for gpu in gpus:
                print(f"GPU {gpu.id}: {gpu.name}")
                print(f"  Core Usage: {gpu.load*100:.1f}%")
                print(f"  Memory Usage: {gpu.memoryUtil*100:.1f}%")
        else:
            print("\nNo GPU detected")
        return gpus
    except Exception as e:
        print(f"Error getting GPU usage: {e}")
        return None

import schedule
import time

def monitor_job():
    try:
        # Get server IP (use first non-local IPv4 address)
        ip = None
        for interface, addrs in psutil.net_if_addrs().items():
            for addr in addrs:
                if addr.family == 2 and not addr.address.startswith('127.'):
                    ip = addr.address
                    break
            if ip:
                break
        ip = ip or 'unknown'

        print(f"\n[{time.strftime('%Y-%m-%d %H:%M:%S')}] Monitoring...")
        cpu_usage = get_cpu_usage()
        disk_total, disk_usage = get_disk_usage()
        gpus = get_gpu_usage()
        
        if None not in [cpu_usage, disk_total, disk_usage, gpus]:
            try:
                save_to_db(ip, cpu_usage, disk_total, disk_usage, gpus)
            except Exception as e:
                print(f"Database operation failed (will continue): {e}")
    except Exception as e:
        print(f"Monitoring error (will continue): {e}")

if __name__ == "__main__":
    # Run immediately first time
    monitor_job()
    
    # Schedule to run every minute
    schedule.every(1).hours.do(monitor_job)
    
    while True:
        schedule.run_pending()
        time.sleep(1)
